﻿namespace JunFan.Tests.UnitTests
{
    using System;
    using Domain;
    using FluentAssertions;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Infrastructure;

    [TestClass]
    public class AddingItem
    {
        [TestInitialize]
        public void InitializeBoard()
        {
            UnitTestContext.InitBoard();
        }

        /// <summary>
        /// Given: A new Item with Id and Description without Creation date
        /// When: Adding the item
        /// Then: Created date should be Today
        /// </summary>
        [TestMethod]
        public void ShouldBeAddedWithDefaultCreatedDate()
        {
            // Given
            var item = Given.NewItem
                .CreatedOn(default(DateTime)) // null creation date
                .Build();

            // When
            var actualItem = When.AddingItem(item);

            // Then
            actualItem.CreatedOn.Should().Be(DateTime.Today);
        }

        /// <summary>
        /// Given: A new Item with Creation date in the past
        /// When: Adding the item
        /// Then: Created date should be equal the given creation date.
        /// </summary>
        [TestMethod]
        public void ShouldBeAddedWithPastCreatedDate()
        {
            DateTime creationDateInThePast = DateTime.Today.AddDays(-10).AddMonths(-1);
            
            var item = Given.NewItem
                .CreatedOn(creationDateInThePast)
                .Build();

            var actualItem = When.AddingItem(item);

            actualItem.CreatedOn.Should().Be(creationDateInThePast);
        }

        /// <summary>
        /// Given: A new Item
        /// When: Adding the item
        /// Then: Completed date shoul be null
        /// </summary>
        [TestMethod]
        public void ShouldHaveCompletedDateNull()
        {
            var newItem = Given.NewItem.Build();

            var actualItem = When.AddingItem(newItem);

            actualItem.CompletedOn.Should().Be(null);
        }

        /// <summary>
        /// Given: An existent item with a unique Id
        /// When: Add an new item with the same Id
        /// Then: Adding should fail
        /// </summary>
        [TestMethod]
        public void ShouldHaveAnUniqueId()
        {
            var existentItem = Given.NewItem.Added(UnitTestContext.Board);

            // When
            var duplicatedIdItem = new Item { Id = existentItem.Id };
            Action action = () => UnitTestContext.Board.AddItem(duplicatedIdItem);

            action.ShouldThrow<BusinessRuleException>()
                  .WithMessage(string.Format("Item Id should be unique and there is an item with id '{0}' already.", duplicatedIdItem.Id), ComparisonMode.EquivalentSubstring);
        }
    }
}